package com.hskn.hss.task;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.constant.CommonConstant;
import com.hskn.hss.module.alarmcar.entity.AlarmCar;
import com.hskn.hss.module.alarmcar.mapper.AlarmCarMapper;
import com.hskn.hss.module.alarmperson.entity.AlarmPerson;
import com.hskn.hss.module.alarmperson.mapper.AlarmPersonMapper;
import com.hskn.hss.module.carTrack.entity.CarTrack;
import com.hskn.hss.module.carTrack.mapper.CarTrackMapper;
import com.hskn.hss.module.coverexp.entity.TlCoverExp;
import com.hskn.hss.module.coverexp.mapper.CoverExpMapper;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.impl.SysDepartServiceImpl;
import com.hskn.hss.module.employeeTrack.entity.EmployeeTrack;
import com.hskn.hss.module.employeeTrack.mapper.EmployeeTrackMapper;
import com.hskn.hss.module.employeeTrack.vo.RandomDateVo;
import com.hskn.hss.module.kfkanalyse.service.IkfkAnalyseService;
import com.hskn.hss.module.kfkdeal.service.impl.KfkDealServiceImpl;
import com.hskn.hss.module.kfkhumancamer.entity.KfkHumanCamer;
import com.hskn.hss.module.kfkhumancamer.mapper.KfkHumanCamerMapper;
import com.hskn.hss.module.kfkinterphone.entity.KfkInterphone;
import com.hskn.hss.module.kfkinterphone.mapper.KfkInterphoneMapper;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlcartype.entity.TlCarType;
import com.hskn.hss.module.tlcartype.service.ITlCarTypeService;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.tlemployee.service.ITlEmployeeService;
import com.hskn.hss.module.tlequip.entity.TlEquip;
import com.hskn.hss.module.tlequip.mapper.TlEquipMapper;
import com.hskn.hss.module.tlequip.service.impl.TlEquipServiceImpl;
import com.hskn.hss.module.tlfacilities.entity.TlFacilities;
import com.hskn.hss.module.tlfacilities.mapper.TlFacilitiesMapper;
import com.hskn.hss.module.tlthreshold.entity.TlThreshold;
import com.hskn.hss.module.tlthreshold.mapper.TlThresholdMapper;
import com.hskn.hss.module.tlworktype.entity.TlWorkType;
import com.hskn.hss.module.tlworktype.mapper.TlWorkTypeMapper;
import com.hskn.hss.module.tlworktype.service.ITlWorkTypeService;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.task.entity.CoverMassage;
import com.hskn.hss.task.ienum.WeekUtil;
import com.hskn.hss.utils.*;
import com.hskn.hss.utils.redis.RedisUtil;
import com.hskn.hss.utils.redis.key.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Configuration
@EnableScheduling
public class KfkTask {
    @Autowired
    IkfkAnalyseService ikfkAnalyseService;
    @Resource
    TlCarMapper tlCarMapper;
    @Resource
    TlEquipMapper tlEquipMapper;
    @Resource
    TlEquipServiceImpl tlEquipService;
    @Autowired
    ITlCarService tlCarService;
    @Resource
    TlThresholdMapper tlThresholdMapper;
    @Autowired
    ITlEmployeeService tlEmployeeService;
    @Resource
    AlarmCarMapper alarmCarMapper;
    @Resource
    AlarmPersonMapper alarmPersonMapper;
    @Autowired
    AlarmUtils alarmUtils;
    @Autowired
    LocationUtils locationUtil;
    @Autowired
    private ITlCarTypeService tlCarTypeService;
    @Autowired
    private ITlWorkTypeService tlWorkTypeService;
    @Autowired
    private KfkDealServiceImpl kfkDealService;
    @Resource
    private TlWorkTypeMapper tlWorkTypeMapper;
    @Resource
    private SysDepartMapper sysDepartMapper;
    @Resource
    private EmployeeTrackMapper employeeTrackMapper;
    @Resource
    private CarTrackMapper carTrackMapper;
    @Resource
    private KfkHumanCamerMapper kfkHumanCamerMapper;
    @Resource
    private TlEmployeeMapper tlEmployeeMapper;
    @Resource
    private KfkInterphoneMapper kfkInterphoneMapper;
    @Resource
    private  CoverExpMapper coverExpMapper;
    @Resource
    private TlFacilitiesMapper tlFacilitiesMapper;
    @Resource
    private UserMapper userMapper;
    @Autowired
    private SysDepartServiceImpl sysDepartService;

    @Value("${switch.timed_task}")
    private Boolean timed_task;
    @Value("${kafka.interphone_topic}")
    private String interphone_topic;
    @Value("${kafka.interphone_group}")
    private String interphone_group;
    @Value("${kafka.producer.bootstrap_servers}")
    private String bootstrap_servers;

    /**
     * 更新设备在线状态
     */
    @Scheduled(cron = "0/60 * * * * ?")
    private void calcOnline() {
        if (!timed_task) {
            return;
        }
        log.info("===================60定时任务开始===============");
        long carStartTime = System.currentTimeMillis();

        //查询所有设备
        QueryWrapper<TlEquip> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TlEquip::getStatus, "1");//启用
        queryWrapper.lambda().eq(TlEquip::getBindstatus, "1");//已绑定设备
        List<TlEquip> tlEquipList = tlEquipMapper.selectList(queryWrapper);
        //循环判断并更新设备在线状态
        for (TlEquip tlEquip : tlEquipList) {
            Object online = RedisUtil.get(EquipOnlineKey.token, tlEquip.getEquipcode(), Object.class);
            Integer onlineVideo = RedisUtil.get(EquipOnlineForVideoKey.token, tlEquip.getEquipcode(), Integer.class);
            if (null != online || null != onlineVideo) {//在线
                if (CommonConstant.EQUIP_ONLINE_YES.equals(tlEquip.getOnlinestatus())) {
                    continue;
                }
                tlEquip.setOnlinestatus(CommonConstant.EQUIP_ONLINE_YES);
            } else {//离线
                if (CommonConstant.EQUIP_ONLINE_NO.equals(tlEquip.getOnlinestatus())) {
                    continue;
                }
                tlEquip.setOnlinestatus(CommonConstant.EQUIP_ONLINE_NO);
            }
            tlEquipMapper.updateById(tlEquip);
        }

        long carEndTime = System.currentTimeMillis();
        log.info("===================60定时任务结束===============执行时间(毫秒)：{}", carEndTime - carStartTime);
    }

    @Scheduled(cron = "0 0/3 * * * ? ")  //设备离线报警
    private void offlineAlarm() {
        if (timed_task) {
            String today = DateUtil.formatDate(new Date());
            //查询所有设备
            QueryWrapper<TlEquip> tlEquipQueryWrapper = new QueryWrapper<>();
            tlEquipQueryWrapper.lambda().eq(TlEquip::getStatus, "1");//启用
            tlEquipQueryWrapper.lambda().eq(TlEquip::getBindstatus, "1");//已绑定设备
            Map<String, TlEquip> tlEquipMap = tlEquipService.getTlEquipMapByBindobjidMap(new QueryWrapper<>());

            //查询所有绑设备的人员
            QueryWrapper<TlEmployee> tlEmployeeQueryWrapper = new QueryWrapper<>();
            tlEmployeeQueryWrapper.lambda().eq(TlEmployee::getStatus, "1");//在职
            List<TlEmployee> tlEmployeeList = tlEmployeeMapper.selectList(tlEmployeeQueryWrapper);

            //部门
            Map<String, SysDepart> departMap = sysDepartService.getDepartMap(new QueryWrapper<>());


            String day = DateUtil.formatDate(new Date());
            String startTime = AttributeUtils.timeCompletion(day, 's');
            String endTime = AttributeUtils.timeCompletion(day, 'e');

            log.info("===================人员离线报警开始===============");
            for (TlEmployee tlEmployee : tlEmployeeList) {
                TlEquip tlEquip = tlEquipMap.get(tlEmployee.getId());
                if (Objects.nonNull(tlEquip)) {
                    String eqpnum = tlEquip.getEquipcode();
                    try {
                        String personId = "";
                        int calctime = 0;
                        Map thvalue = alarmUtils.getCompare(eqpnum, "离线");
                        if (thvalue != null && thvalue.size() > 0) {
                            int cmpvalue = Integer.parseInt(String.valueOf(thvalue.get("lx"))) * 60;
                            String objid = String.valueOf(thvalue.get("objid"));
                            String thresholdid = String.valueOf(thvalue.get("thresholdid"));
                            String sysname = String.valueOf(thvalue.get("sysname"));

                            JSONObject param = new JSONObject();
                            param.put("id", objid);
                            personId = tlEmployee.getId();

                            //该人员当天最后一条轨迹数据
                            EmployeeTrack employeeTrack = RedisUtil.get(EmployeeTrackLastOneKeyToday.token, personId + "_" + today, EmployeeTrack.class);
                            if (Objects.isNull(employeeTrack)) {
                                QueryWrapper<EmployeeTrack> queryWrapper = new QueryWrapper<>();
                                queryWrapper.lambda().eq(EmployeeTrack::getEmployeeId, tlEmployee.getId());
                                queryWrapper.lambda().between(EmployeeTrack::getTimestamp, startTime, endTime);
                                queryWrapper.lambda().orderByDesc(EmployeeTrack::getTimestamp);
                                queryWrapper.lambda().last(" LIMIT 1");
                                employeeTrack = employeeTrackMapper.selectOne(queryWrapper);
                            }

                            Date alarmStartTime;
                            if (Objects.nonNull(employeeTrack) && Objects.nonNull(employeeTrack.getTimestamp())) {
                                Date date = employeeTrack.getTimestamp();
                                calctime = StringUtils.getTimeDifference(date).intValue();
                                alarmStartTime = employeeTrack.getTimestamp();
                            } else {
                                calctime = StringUtils.getTimeDifference(StringUtils.getZeroHourToday()).intValue();
                                alarmStartTime = StringUtils.getZeroHourToday();
                            }

                            QueryWrapper<TlThreshold> tlThresholdQueryWrapper = new QueryWrapper<>();
                            tlThresholdQueryWrapper.lambda().eq(TlThreshold::getSysname, "离线");
                            tlThresholdQueryWrapper.lambda().eq(TlThreshold::getItemid, personId);
                            TlThreshold tlThreshold = tlThresholdMapper.selectOne(tlThresholdQueryWrapper);
                            if (Objects.nonNull(thresholdid) && StringUtils.isNotEmpty(tlThreshold.getStatus()) && CommonConstant.THRESHOLD_STATUS_YES.equals(tlThreshold.getStatus())) {
                                if (calctime >= cmpvalue) {

                                    AlarmPerson alarmPerson1 = RedisUtil.get(CarPersonTypeNameLastOneKeyToday.token, tlEmployee.getId() + "_" + "离线" + "_" + today, AlarmPerson.class);

                                    if (Objects.isNull(alarmPerson1)) {
                                        QueryWrapper<AlarmPerson> queryWrapper = new QueryWrapper<>();
                                        queryWrapper.lambda().eq(AlarmPerson::getPersonId, tlEmployee.getId());
                                        queryWrapper.lambda().eq(AlarmPerson::getAlarmTypeName, "离线");
                                        queryWrapper.lambda().between(AlarmPerson::getAlarmTime, startTime, endTime);
                                        queryWrapper.lambda().orderByDesc(AlarmPerson::getAlarmTime);
                                        queryWrapper.lambda().last(" LIMIT 1");
                                        alarmPerson1 = alarmPersonMapper.selectOne(queryWrapper);
                                    }
                                    Boolean flag = true;
                                    if (Objects.nonNull(alarmPerson1) && Objects.nonNull(alarmPerson1.getAlarmEndTime())) {

                                        if (Objects.isNull(employeeTrack) || alarmPerson1.getAlarmEndTime().compareTo(employeeTrack.getTimestamp()) > 0) {
                                            int duration = StringUtils.calLastedTime(alarmPerson1.getAlarmStartTime(), new Date());
                                            String time = StringUtils.s2date(Long.parseLong(String.valueOf(duration)));

                                            alarmPerson1.setIsKeep(1);
                                            alarmPerson1.setAlarmEndTime(new Date());
                                            alarmPerson1.setContent("人员离线超过" + time);
                                            alarmPersonMapper.updateById(alarmPerson1);

                                            //保存更新后的数据
                                            RedisUtil.set(CarPersonTypeNameLastOneKeyToday.token, tlEmployee.getId() + "_" + "离线" + "_" + today, alarmPerson1);
                                            flag = false;
                                        }
                                    }
                                    if (flag) {
                                        AlarmPerson alarmPerson = new AlarmPerson();

                                        QueryWrapper<EmployeeTrack> queryWrapper = new QueryWrapper<>();
                                        queryWrapper.lambda().eq(EmployeeTrack::getEmployeeId, tlEmployee.getId());
                                        queryWrapper.lambda().lt(EmployeeTrack::getTimestamp,new Date());
                                        queryWrapper.lambda().orderByDesc(EmployeeTrack::getTimestamp);
                                        queryWrapper.lambda().last(" LIMIT 1");
                                        EmployeeTrack employeeTrack2 = employeeTrackMapper.selectOne(queryWrapper);

                                        if (Objects.nonNull(employeeTrack2)) {
                                            alarmPerson.setLat(employeeTrack2.getLat());
                                            alarmPerson.setLng(employeeTrack2.getLng());
                                            /** 保存地址 **/
                                            String currentAddress = locationUtil.getAddress(employeeTrack2.getLng(), employeeTrack2.getLat());
                                            if (StringUtils.isNotEmpty(currentAddress)) {
                                                alarmPerson.setAddress(currentAddress);
                                            } else {
                                                alarmPerson.setAddress("");
                                            }
                                            alarmPerson.setAlarmTime(new Date());
                                            alarmPerson.setAlarmTypeId(thresholdid);
                                            alarmPerson.setAlarmTypeName(sysname);
                                            alarmPerson.setCreateTime(new Date());
                                            alarmPerson.setDepId(tlEmployee.getEmpldeptid());
                                            //获取部门名称
                                            SysDepart sysDepart = departMap.get(tlEmployee.getEmpldeptid());
                                            if (Objects.nonNull(sysDepart)) {
                                                alarmPerson.setDepName(sysDepart.getDepartName());
                                            }

                                            alarmPerson.setPersonId(tlEmployee.getId());
                                            alarmPerson.setPersonName(tlEmployee.getName());
                                            String personTypeId = "";
                                            String personTypeName = "";
                                            if (Objects.nonNull(tlEmployee) && StringUtils.isNotEmpty(tlEmployee.getWorktype())) {
                                                personTypeId = tlEmployee.getWorktype();
                                                TlWorkType tlWorkType = tlWorkTypeService.getFromRedis(personTypeId);
                                                if (Objects.nonNull(tlWorkType) && StringUtils.isNotEmpty(tlWorkType.getWorktype())) {
                                                    personTypeName = tlWorkType.getWorktype();
                                                }
                                            }
                                            alarmPerson.setPersonTypeId(personTypeId);
                                            alarmPerson.setPersonTypeName(personTypeName);
                                            alarmPerson.setAlarmStartTime(alarmStartTime);
                                            alarmPerson.setAlarmEndTime(new Date());

                                            int duration = StringUtils.calLastedTime(alarmStartTime, new Date());
                                            String time = StringUtils.s2date(Long.parseLong(String.valueOf(duration)));
                                            alarmPerson.setContent("人员离线超过" + time);

                                            alarmPersonMapper.insert(alarmPerson);

                                            //保存更新后的数据
                                            RedisUtil.set(CarPersonTypeNameLastOneKeyToday.token, tlEmployee.getId() + "_" + "离线" + "_" + today, alarmPerson);

                                            //推送消息
                                            TlWorkType tlWorkType = tlWorkTypeMapper.selectById(tlEmployee.getWorktype());
                                            kfkDealService.sendEmployeeAlarm(alarmPerson.getLng(), alarmPerson.getLat(), new Date(), tlEmployee, tlWorkType, alarmPerson.getAddress(), alarmPerson.getId(), CommonConstant.PUSH_TYPE_ALARM, "离线");
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("offlineAlarm，empResultList报错，eqpnum=" + eqpnum, e);
                    }
                }
            }

            //查询所有绑设备的车辆
            QueryWrapper<TlCar> tlCarQueryWrapper = new QueryWrapper<>();
            tlCarQueryWrapper.lambda().eq(TlCar::getStatus, "1");//正常
            List<TlCar> tlCarList = tlCarMapper.selectList(tlCarQueryWrapper);

            for (TlCar tlCar : tlCarList) {
                if (Objects.nonNull(tlCar)) {
                    TlEquip tlEquip = tlEquipMap.get(tlCar.getId());
                    if (Objects.nonNull(tlEquip)) {
                        String eqpnum = String.valueOf(tlEquip.getEquipcode());
                        try {
                            String carId = "";
                            int calctime = 0;
                            Map thvalue = alarmUtils.getCompare(eqpnum, "离线");
                            if (thvalue != null && thvalue.size() > 0) {
                                int cmpvalue = Integer.parseInt(String.valueOf(thvalue.get("lx"))) * 60;
                                String objid = String.valueOf(thvalue.get("objid"));
                                String thresholdid = String.valueOf(thvalue.get("thresholdid"));
                                String sysname = String.valueOf(thvalue.get("sysname"));

                                JSONObject param = new JSONObject();
                                param.put("id", objid);
                                carId = tlCar.getId();

                                //该车辆当天最后一条轨迹数据
                                CarTrack carTrack = RedisUtil.get(CarTrackLastOneKeyToday.token, carId + "_" + today, CarTrack.class);
                                if (Objects.isNull(carTrack)) {
                                    QueryWrapper<CarTrack> queryWrapper = new QueryWrapper<>();
                                    queryWrapper.lambda().eq(CarTrack::getCarId, carId);
                                    queryWrapper.lambda().between(CarTrack::getTimestamp, startTime, endTime);
                                    queryWrapper.lambda().orderByDesc(CarTrack::getTimestamp);
                                    queryWrapper.lambda().last(" LIMIT 1");
                                    carTrack = carTrackMapper.selectOne(queryWrapper);
                                }

                                Date alarmStartTime;
                                if (Objects.nonNull(carTrack) && Objects.nonNull(carTrack.getTimestamp())) {
                                    Date date = carTrack.getTimestamp();
                                    calctime = StringUtils.getTimeDifference(date).intValue();
                                    alarmStartTime = carTrack.getTimestamp();
                                } else {
                                    calctime = StringUtils.getTimeDifference(StringUtils.getZeroHourToday()).intValue();
                                    alarmStartTime = StringUtils.getZeroHourToday();
                                }

                                QueryWrapper<TlThreshold> tlThresholdQueryWrapper = new QueryWrapper<>();
                                tlThresholdQueryWrapper.lambda().eq(TlThreshold::getSysname, "离线");
                                tlThresholdQueryWrapper.lambda().eq(TlThreshold::getItemid, carId);
                                TlThreshold tlThreshold = tlThresholdMapper.selectOne(tlThresholdQueryWrapper);
                                if (Objects.nonNull(thresholdid) && StringUtils.isNotEmpty(tlThreshold.getStatus()) && CommonConstant.THRESHOLD_STATUS_YES.equals(tlThreshold.getStatus())) {
                                    if (calctime >= cmpvalue) {

                                        AlarmCar alarmCar1 = RedisUtil.get(CarAlarmTypeNameLastOneKeyToday.token, carId + "_" + "离线" + "_" + today, AlarmCar.class);

                                        if (Objects.isNull(alarmCar1)) {
                                            QueryWrapper<AlarmCar> queryWrapper = new QueryWrapper<>();
                                            queryWrapper.lambda().eq(AlarmCar::getCarId, carId);
                                            queryWrapper.lambda().eq(AlarmCar::getAlarmTypeName, "离线");
                                            queryWrapper.lambda().between(AlarmCar::getAlarmTime, startTime, endTime);
                                            queryWrapper.lambda().orderByDesc(AlarmCar::getAlarmTime);
                                            queryWrapper.lambda().last(" LIMIT 1");
                                            alarmCar1 = alarmCarMapper.selectOne(queryWrapper);
                                        }
                                        Boolean flag = true;
                                        if (Objects.nonNull(alarmCar1) && Objects.nonNull(alarmCar1.getAlarmEndTime())) {

                                            if (alarmCar1.getAlarmEndTime().compareTo(alarmStartTime) > 0) {
                                                int duration = StringUtils.calLastedTime(alarmStartTime, new Date());
                                                String time = StringUtils.s2date(Long.parseLong(String.valueOf(duration)));

                                                //离线持续保持时间
                                                alarmCar1.setContent("设备离线超过" + time);
                                                alarmCar1.setIsKeep(1);
                                                alarmCar1.setAlarmEndTime(new Date());
                                                int i = alarmCarMapper.updateById(alarmCar1);
                                                if (i > 0) {
                                                    //保存更新后的数据
                                                    RedisUtil.set(CarAlarmTypeNameLastOneKeyToday.token, carId + "_" + "离线" + "_" + today, alarmCar1);
                                                    flag = false;
                                                }
                                            }
                                        }
                                        if (flag) {
                                            AlarmCar alarmCar = new AlarmCar();

                                            QueryWrapper<CarTrack> queryWrapper = new QueryWrapper<>();
                                            queryWrapper.lambda().eq(CarTrack::getCarId, carId);
                                            queryWrapper.lambda().lt(CarTrack::getTimestamp,new Date());
                                            queryWrapper.lambda().orderByDesc(CarTrack::getTimestamp);
                                            queryWrapper.lambda().last(" LIMIT 1");
                                            CarTrack carTrack2 = carTrackMapper.selectOne(queryWrapper);

                                            if (Objects.nonNull(carTrack2)) {
                                                alarmCar.setLat(carTrack2.getLat());
                                                alarmCar.setLng(carTrack2.getLng());
                                                /** 保存地址 **/
                                                String currentAddress = locationUtil.getAddress(carTrack2.getLng(), carTrack2.getLat());
                                                if (StringUtils.isNotEmpty(currentAddress)) {
                                                    alarmCar.setAddress(currentAddress);
                                                } else {
                                                    alarmCar.setAddress("");
                                                }

                                                alarmCar.setCarId(carId);
                                                alarmCar.setCarName(tlCar.getCarnumber());
                                                alarmCar.setDepId(tlCar.getCardeptid());

                                                //获取部门名称
                                                SysDepart sysDepart = departMap.get(tlCar.getCardeptid());
                                                if (Objects.nonNull(sysDepart)) {
                                                    alarmCar.setDepName(sysDepart.getDepartName());
                                                }

                                                alarmCar.setCreateTime(new Date());
                                                alarmCar.setAlarmTime(new Date());
                                                alarmCar.setAlarmTypeId(thresholdid);
                                                alarmCar.setAlarmTypeName(sysname);

                                                //根据carId查询type
                                                TlCar tlCar2 = tlCarMapper.selectById(alarmCar.getCarId());
                                                String typeId = "";
                                                String typeName = "";
                                                if (Objects.nonNull(tlCar2) && StringUtils.isNotEmpty(tlCar2.getCartypeid())) {
                                                    typeId = tlCar2.getCartypeid();
                                                    TlCarType tlCarType = tlCarTypeService.getFromRedis(tlCar2.getCartypeid());
                                                    if (Objects.nonNull(tlCarType) && StringUtils.isNotEmpty(tlCarType.getTypename())) {
                                                        typeName = tlCarType.getTypename();
                                                    }
                                                }
                                                alarmCar.setCarTypeId(typeId);
                                                alarmCar.setCarTypeName(typeName);
                                                alarmCar.setAlarmStartTime(alarmStartTime);
                                                alarmCar.setAlarmEndTime(new Date());

                                                int duration = StringUtils.calLastedTime(alarmStartTime, new Date());
                                                String time = StringUtils.s2date(Long.parseLong(String.valueOf(duration)));
                                                alarmCar.setContent("设备离线超过" + time);
                                                alarmCar.setAlarmValue(new BigDecimal(duration));
                                                alarmCarMapper.insert(alarmCar);

                                                //保存更新后的数据
                                                RedisUtil.set(CarAlarmTypeNameLastOneKeyToday.token, carId + "_" + "离线" + "_" + today, alarmCar);

                                                // 发送违规信息到前台
                                                String remindKey = AlarmUtils.changeCarAlarmName(sysname);
                                                JSONObject alarmJson = new JSONObject();
                                                alarmJson.put("model", CommonConstant.PUSH_TYPE_ALARM);
                                                JSONObject detailJson = new JSONObject();
                                                detailJson.put("id", alarmCar.getAlarmCarId());
                                                detailJson.put("remindKey", remindKey);
                                                detailJson.put("happenTime", DateUtil.formatDateTime(new Date()));
                                                detailJson.put("lng", alarmCar.getLng());
                                                detailJson.put("lat", alarmCar.getLat());
                                                detailJson.put("address", alarmCar.getAddress());
                                                detailJson.put("pic", tlCar.getCarpicture());
                                                detailJson.put("typeId", tlCar.getCartypeid());
                                                detailJson.put("typeName", "离线");
                                                detailJson.put("authorId", tlCar.getId());
                                                detailJson.put("authorName", tlCar.getCarnumber());
                                                detailJson.put("authorType", "car");
                                                alarmJson.put("detail", detailJson);
                                                WebSocketUtils.sendMessageToAll(alarmJson.toString());
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("offlineAlarm，empResultList报错，eqpnum=" + eqpnum, e);
                        }
                    }
                }

            }
        }
    }

    @Scheduled(cron = "0 0 0 */1 * ?")  //更新人流摄像机日最大记录表
    public void updateHumanCamer() {
        if (timed_task) {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DATE, -1);
            String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
            Date startTime = DateUtil.parseDateTime(yesterday + " 00:00:00");
            Date endTime = DateUtil.parseDateTime(yesterday + " 23:59:59");
            KfkHumanCamer humanCamer = new KfkHumanCamer();
            humanCamer.setStartTime(startTime);
            humanCamer.setEndTime(endTime);
            kfkHumanCamerMapper.insertHumanCamer(humanCamer);
        }
    }

    @Scheduled(cron = "0 0/1 * * * ?")  //更新曹辰明和赵娜
    public void updatePerson() {
        if (timed_task) {
            log.info("----------------------------更新曹辰明和赵娜开始--------------------------------------------------");
            Map<String, Object> configs = new HashMap<>();
            configs.put("bootstrap.servers",bootstrap_servers);
            configs.put("group.id",3);
            configs.put("enable.auto.commit",false);
            configs.put("auto.commit.interval.ms",1000);
            configs.put("auto.offset.reset","latest");
            configs.put("acks","all");
            configs.put("retries",2);
            configs.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
            configs.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
            KafkaProducer<String, String> producer = new KafkaProducer<>(configs);
            //季传顺
            String day1 = RedisUtil.get(RandomDateToday.token, "8986111829103268063", String.class);
            log.info("----------------------------曹辰明调取季传顺"+day1+"的数据--------------------------------------------------");
            //高秀美
            String day2 = RedisUtil.get(RandomDateToday.token, "8986111829103268064", String.class);
            log.info("----------------------------赵娜调取高秀美"+day1+"的数据--------------------------------------------------");

            if (StringUtils.isEmpty(day1)){
                List<RandomDateVo> randomDateList = employeeTrackMapper.getRandomDate("8986111829103268063");
                Random r = new Random(1);
                int i = r.nextInt(randomDateList.size());
                Map<Integer, RandomDateVo> randomDateVoMap = randomDateList.stream().collect(Collectors.groupingBy(RandomDateVo::getNumber, Collectors.collectingAndThen(Collectors.toList(), a -> a.get(0))));
                day1 = randomDateVoMap.get(i).getWorkDay();
                RedisUtil.set(RandomDateToday.token, "8986111829103268063", day1);
            }
            if (StringUtils.isEmpty(day2)){
                List<RandomDateVo> randomDateList = employeeTrackMapper.getRandomDate("8986111829103268064");
                Random r = new Random(1);
                int i = r.nextInt(randomDateList.size());
                Map<Integer, RandomDateVo> randomDateVoMap = randomDateList.stream().collect(Collectors.groupingBy(RandomDateVo::getNumber, Collectors.collectingAndThen(Collectors.toList(), a -> a.get(0))));
                day2 = randomDateVoMap.get(i).getWorkDay();
                RedisUtil.set(RandomDateToday.token, "8986111829103268064", day2);
            }
            try {
                QueryWrapper<KfkInterphone> kfkInterphoneQueryWrapper1 = new QueryWrapper<>();
                kfkInterphoneQueryWrapper1.lambda().orderByAsc(KfkInterphone::getDeviceTime);
                kfkInterphoneQueryWrapper1.lambda().eq(KfkInterphone::getEqpnum, "8986111829103268063");
                String startTime1 = day1 + " " + DateUtil.thisHour(true) + ":" + DateUtil.thisMinute() + ":00";
                String endTime1 = day1 + " " + DateUtil.thisHour(true) + ":" + DateUtil.thisMinute() + ":59";
                kfkInterphoneQueryWrapper1.lambda().between(KfkInterphone::getDeviceTime, startTime1, endTime1);
                List<KfkInterphone> kfkInterphones1 = kfkInterphoneMapper.selectList(kfkInterphoneQueryWrapper1);
                log.info("----------------------------调取季传顺"+startTime1+"到"+endTime1+"的数据--------------------------------------------------");
                System.out.println("a5");
                kfkInterphones1.forEach(t->{
                    //车辆轨迹queryWrapper
                    Date date = DateUtil.parseDateTime(DateUtil.formatDate(new Date()) + " " + DateUtil.formatTime(t.getTimestamp()));
                    KfkInterphone kfkInterphone = new KfkInterphone();
                    kfkInterphone.setEqpnum("8886031743206710801");
                    kfkInterphone.setAccount("8886031743206710801");
                    kfkInterphone.setLat(t.getLat());
                    kfkInterphone.setLon(t.getLon());
                    kfkInterphone.setSpeed(t.getSpeed());
                    kfkInterphone.setDirection(t.getDirection());
                    System.out.println("a6");
                    //后一天
                    String dateTime = DateUtil.format(date, "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                    log.info("----------------------------推送曹辰明"+dateTime+"的数据--------------------------------------------------");
                    String aa = "{\n" +
                            "    \"no\":\"" + kfkInterphone.getEqpnum() + "\",\n" +
                            "    \"deviceType\":\"INTERPHONE\",\n" +
                            "    \"state\":1,\n" +
                            "    \"content\":{\n" +
                            "        \"type\":\"INTERPHONE_REPORT\",\n" +
                            "        \"info\":{\n" +
                            "            \"Account\":" + kfkInterphone.getAccount() + ",\n" +
                            "            \"Lat\":" + kfkInterphone.getLat() + ",\n" +
                            "            \"Lon\":" + kfkInterphone.getLon() + ",\n" +
                            "            \"Time\":\"" + dateTime + "\",\n" +
                            "            \"Speed\":" + kfkInterphone.getSpeed().intValue() + ",\n" +
                            "            \"Direction\":" + kfkInterphone.getDirection().intValue() + "" +
                            "        }\n" +
                            "    }\n" +
                            "}";
                    System.out.println(aa);
                    producer.produce(interphone_topic, 0, null, aa, (metadata, exception) -> {
                        if (exception != null) {
                            exception.printStackTrace();
                            return;
                        }
                        System.out.println("produce msg completed");
                    });
                });

                QueryWrapper<KfkInterphone> kfkInterphoneQueryWrapper2 = new QueryWrapper<>();
                kfkInterphoneQueryWrapper2.lambda().orderByAsc(KfkInterphone::getDeviceTime);
                kfkInterphoneQueryWrapper2.lambda().eq(KfkInterphone::getEqpnum, "8986111829103268064");
                String startTime2 = day1 + " " + DateUtil.thisHour(true) + ":" + DateUtil.thisMinute() + ":00";
                String endTime2 = day1 + " " + DateUtil.thisHour(true) + ":" + DateUtil.thisMinute() + ":59";
                kfkInterphoneQueryWrapper2.lambda().between(KfkInterphone::getDeviceTime, startTime2, endTime2);
                List<KfkInterphone> kfkInterphones2 = kfkInterphoneMapper.selectList(kfkInterphoneQueryWrapper2);
                log.info("----------------------------调取高秀美"+startTime1+"到"+endTime1+"的数据--------------------------------------------------");
                kfkInterphones2.forEach(t->{
                    //车辆轨迹queryWrapper
                    Date date = DateUtil.parseDateTime(DateUtil.formatDate(new Date()) + " " + DateUtil.formatTime(t.getTimestamp()));
                    KfkInterphone kfkInterphone = new KfkInterphone();
                    kfkInterphone.setEqpnum("8886031743206710802");
                    kfkInterphone.setAccount("8886031743206710802");
                    kfkInterphone.setLat(t.getLat());
                    kfkInterphone.setLon(t.getLon());
                    kfkInterphone.setSpeed(t.getSpeed());
                    kfkInterphone.setDirection(t.getDirection());
                    //后一天
                    String dateTime = DateUtil.format(date, "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                    log.info("----------------------------推送赵娜"+dateTime+"的数据--------------------------------------------------");
                    String aa = "{\n" +
                            "    \"no\":\"" + kfkInterphone.getEqpnum() + "\",\n" +
                            "    \"deviceType\":\"INTERPHONE\",\n" +
                            "    \"state\":1,\n" +
                            "    \"content\":{\n" +
                            "        \"type\":\"INTERPHONE_REPORT\",\n" +
                            "        \"info\":{\n" +
                            "            \"Account\":" + kfkInterphone.getAccount() + ",\n" +
                            "            \"Lat\":" + kfkInterphone.getLat() + ",\n" +
                            "            \"Lon\":" + kfkInterphone.getLon() + ",\n" +
                            "            \"Time\":\"" + dateTime + "\",\n" +
                            "            \"Speed\":" + kfkInterphone.getSpeed().intValue() + ",\n" +
                            "            \"Direction\":" + kfkInterphone.getDirection().intValue() + "" +
                            "        }\n" +
                            "    }\n" +
                            "}";
                    System.out.println(aa);
                    producer.produce(interphone_topic, 0, null, aa, (metadata, exception) -> {
                        if (exception != null) {
                            exception.printStackTrace();
                            return;
                        }
                        System.out.println("produce msg completed");
                    });
                });
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                producer.close();
            }
            log.info("----------------------------更新曹辰明和赵娜结束--------------------------------------------------");
        }
    }

    @Scheduled(cron = "0 0/1 * * * ?") //窨井盖自检提醒
    public void coverRemind(){
        if(timed_task){
            log.info("===================窨井盖自检提醒-获取系统时间===============");
            //判断小时分钟（每月周用）
            String remindTime;
            //判断月日小时分钟（每年用）
            String remindTimey;
            //当月最后一天
            String lastDay;

            //系统时间(HH:mm)
            String nowTime;
            //系统时间(MM-dd HH:mm)
            String nowTimey;
            //系统时间(EEE)
            String nowTimew;
            //系统时间(dd)
            String nowTimem;


            //取得当前系统时间
            Date nowDate=new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowDate);
            calendar.add(calendar.DATE, 0);
            nowDate = calendar.getTime();
            //取得当月最后一天
            Date lastDate=new Date();
            Calendar last = Calendar.getInstance();
            last.set(Calendar.DAY_OF_MONTH, last.getActualMaximum(Calendar.DAY_OF_MONTH));
            lastDate = last.getTime();

            //时间格式实例
            List<TlCoverExp> tlCoverExps1 = new ArrayList<>();
            SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
            SimpleDateFormat formatYear = new SimpleDateFormat("MM-dd HH:mm");
            SimpleDateFormat formatWeek = new SimpleDateFormat("EEE");
            SimpleDateFormat formatMonth = new SimpleDateFormat("dd");
            //系统时间拆分
            nowTimey = formatYear.format(nowDate);
            nowTimew = formatWeek.format(nowDate);
            nowTimem = formatMonth.format(nowDate);
            nowTime = formatter.format(nowDate);
            //当月最后一天赋值
            lastDay = formatter.format(lastDate);

            log.info("===================窨井盖自检提醒开始========================");

            //获取全部自检提醒数据
            QueryWrapper<TlCoverExp> tlCoverExpQueryWrapper = new QueryWrapper<>();
            tlCoverExpQueryWrapper.lambda().isNotNull(TlCoverExp::getRemindType);
            List<TlCoverExp> tlCoverExps = coverExpMapper.selectList(tlCoverExpQueryWrapper);

            if(tlCoverExps.size()>0){
                //获取与当前时间节点相同的数据
                for(TlCoverExp cv : tlCoverExps){
                    remindTime = formatter.format(cv.getRemindTime());
                    remindTimey = formatYear.format(cv.getRemindTime());
                    //判断每年提醒
                    if(cv.getRemindType().equals("2") && remindTimey.equals(nowTimey)
                    ){
                        tlCoverExps1.add(cv);
                        //判断每周提醒
                    } else if(cv.getRemindType().equals("0")
                            && WeekUtil.RemindWeek(cv.getRemindDay()).equals(nowTimew)
                            && remindTime.equals(nowTime)
                    ){
                        tlCoverExps1.add(cv);
                        //判断每月提醒
                    } else if(cv.getRemindType().equals("1") && remindTime.equals(nowTime)){
                        if(nowTimem.compareTo(cv.getRemindDay()) == 0 ){
                            tlCoverExps1.add(cv);
                            //判断当日是否为本月最后一天且提醒时间大于今天
                        }else if(nowTimem.compareTo(lastDay) == 0 && cv.getRemindDay().compareTo(nowTimem) == 1){
                            tlCoverExps1.add(cv);
                        }
                    }
                }

                //获取筛选后窨井盖id
                List<String> maintbids = tlCoverExps1.stream().map(TlCoverExp::getMaintbid).collect(Collectors.toList());

                if(CollectionUtils.isNotEmpty(maintbids) && maintbids.size()>0){
                    //取得设施档案窨井盖信息
                    QueryWrapper<TlFacilities> tlFacilitiesQueryWrapper = new QueryWrapper<>();
                    tlFacilitiesQueryWrapper.lambda().in(TlFacilities::getId,maintbids);
                    List<TlFacilities> tlFacilitiesList = tlFacilitiesMapper.selectList(tlFacilitiesQueryWrapper);

                    //获取不为空的维护单位id
                    List<String> mtadeptids = tlFacilitiesList.stream().filter(t-> StringUtils.isNotEmpty(t.getMtadeptid()))
                            .map(TlFacilities::getMtadeptid).distinct().collect(Collectors.toList());

                    //从部门表查询维护单位名称
                    if(CollectionUtils.isNotEmpty(mtadeptids) && mtadeptids.size()>0){
                        QueryWrapper<SysDepart> sysDepartQueryWrapper = new QueryWrapper<>();
                        sysDepartQueryWrapper.lambda().in(SysDepart::getId,mtadeptids);
                        List<SysDepart> sysDepartList = sysDepartMapper.selectList(sysDepartQueryWrapper);

                        //维护单位名称的整合
                        if(CollectionUtils.isNotEmpty(sysDepartList) && sysDepartList.size()>0){
                            for(TlFacilities fac : tlFacilitiesList){
                                for(SysDepart sys: sysDepartList){
                                    if(fac.getMtadeptid().equals(sys.getId())){
                                        fac.setMtadeptname(sys.getDepartName());
                                    }
                                }
                            }
                        }
                    }

                    //获取不为空的责任人id
                    List<String> principals = tlFacilitiesList.stream().filter(t-> StringUtils.isNotEmpty(t.getPrincipal()))
                            .map(TlFacilities::getPrincipal).distinct().collect(Collectors.toList());

                    //通过人员id查询姓名和联系方式
                    if(CollectionUtils.isNotEmpty(principals) && principals.size()>0){
                        QueryWrapper<User> tlEmployeeQueryWrapper = new QueryWrapper<>();
                        tlEmployeeQueryWrapper.lambda().in(User ::getUid,principals);
                        List<User> tlEmployeeList = userMapper.selectList(tlEmployeeQueryWrapper);

                        //责任人姓名联系方式的整合
                        if(CollectionUtils.isNotEmpty(tlEmployeeList) && tlEmployeeList.size()>0){
                            for(TlFacilities fac : tlFacilitiesList){
                                for(User emp: tlEmployeeList){
                                    if(fac.getPrincipal().equals(emp.getUid())){
                                        fac.setPrincipalname(emp.getName());
                                        //联系方式在备注字段临时存储
                                        fac.setRemark(emp.getPhone());
                                    }
                                }
                            }
                        }
                    }

                    //从窨井盖信息中提取推送信息
                    if(CollectionUtils.isNotEmpty(tlFacilitiesList)){

                        JSONObject remindJson = new JSONObject();
                        JSONObject detail = new JSONObject();
                        List<CoverMassage> coverList = new ArrayList<>();
                        for(TlFacilities fac : tlFacilitiesList){
                            CoverMassage coverMassage = new CoverMassage();
                            if(StringUtils.isEmpty(fac.getMtadeptname())){
                                fac.setMtadeptname("");
                            }
                            if(StringUtils.isEmpty(fac.getPrincipalname())){
                                fac.setPrincipalname("");
                            }
                            if(StringUtils.isEmpty(fac.getRemark())){
                                fac.setRemark("");
                            }
                            //从自检提醒表中获取自检周期以及周期内次数
                            for(TlCoverExp cov: tlCoverExps1){
                                if(cov.getMaintbid().equals(fac.getId())){
                                    //自检周期
                                    coverMassage.setInsType(cov.getInsType());
                                    //周期内次数
                                    coverMassage.setIns(cov.getIns());
                                }
                            }
                            //井盖类型
                            coverMassage.setFacltypeitemname(fac.getFacltypeitemname());
                            //井盖名称
                            coverMassage.setFaclname(fac.getFaclname());
                            //所属机构
                            coverMassage.setFacldeptname(fac.getFacldeptname());
                            //维护单位
                            coverMassage.setMtadeptname(fac.getMtadeptname());
                            //责任人姓名
                            coverMassage.setPrincipalname(fac.getPrincipalname());
                            //责任人联系方式
                            coverMassage.setRemark(fac.getRemark());
                            //设施地址中文描述
                            coverMassage.setFacladdrdetail(fac.getFacladdrdetail());
                            //设施地址
                            coverMassage.setFacladdr(fac.getFacladdr());
                            //存入JsonList
                            coverList.add(coverMassage);
                        }
                        remindJson.put("model", 7);
                        detail.put("remindKey","manholeAlarmPatrolReminder");
                        detail.put("data",coverList);
                        remindJson.put("detail",detail);

                        //发送提醒序列到前台
                        WebSocketUtils.sendMessageToAll(remindJson.toString());
                    }
                }
            }
            log.info("===================窨井盖自检提醒结束========================");
        }
    }
}
